From 1f13726ffb2d96da6b48fe3fa551d6f994fc7a2c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 5 Jul 2026 08:59:27 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Improve=20accessibili?= =?UTF-8?q?ty=20of=20list=20actions=20with=20dynamic=20context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added dynamic context to `.help()` and `.accessibilityLabel()` modifiers for the Edit and Delete buttons in `MacroListView.swift` and `ScriptListView.swift`. Previously, these icon-only buttons relied on static labels like "Edit" or "Delete", which caused disambiguation issues for screen reader users and tooltip confusion when navigating repeated lists. The labels now intelligently fallback to the item's name or a default if empty (e.g., "Edit Script Name" or "Delete Macro Name"), ensuring a fully accessible and intuitive micro-UX experience. Co-authored-by: NSEvent <44446865+NSEvent@users.noreply.github.com> --- .Jules/palette.md | 3 +++ .../Views/Macros/MacroListView.swift | 12 ++++++------ .../Views/Scripts/ScriptListView.swift | 8 ++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index f61603c8..73dab83a 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -25,3 +25,6 @@ ## 2026-06-23 - [SwiftUI Button Accessibility] **Learning:** Found a pattern where SwiftUI icon-only buttons or minimal UI elements were given `.help()` modifiers for hover tooltips but lacked `.accessibilityLabel()` modifiers for screen readers. **Action:** When adding `.help()` to buttons, always pair it with a corresponding `.accessibilityLabel()` to ensure full accessibility. +## 2026-07-05 - [Dynamic Context for List Actions] +**Learning:** In repeated lists or loops, action buttons (like Edit/Delete) require dynamic context in their `.help()` and `.accessibilityLabel()` modifiers (e.g., fallback to 'Unnamed' if empty) to disambiguate the action for screen reader users and prevent confusion. +**Action:** Ensure dynamic labels are applied to all list items. diff --git a/XboxControllerMapper/XboxControllerMapper/Views/Macros/MacroListView.swift b/XboxControllerMapper/XboxControllerMapper/Views/Macros/MacroListView.swift index 211ecb1e..b2ce8c8f 100644 --- a/XboxControllerMapper/XboxControllerMapper/Views/Macros/MacroListView.swift +++ b/XboxControllerMapper/XboxControllerMapper/Views/Macros/MacroListView.swift @@ -155,8 +155,8 @@ struct SharedMacroRow: View { .foregroundColor(.accentColor) } .buttonStyle(.borderless) - .help("Edit in shared library") - .accessibilityLabel("Edit in shared library") + .help(macro.name.isEmpty ? "Edit in shared library" : "Edit \(macro.name) in shared library") + .accessibilityLabel(macro.name.isEmpty ? "Edit in shared library" : "Edit \(macro.name) in shared library") } .padding(.horizontal, 12) .padding(.vertical, 8) @@ -206,16 +206,16 @@ struct MacroRow: View { .foregroundColor(.accentColor) } .buttonStyle(.borderless) - .help("Edit") - .accessibilityLabel("Edit") + .help(macro.name.isEmpty ? "Edit" : "Edit \(macro.name)") + .accessibilityLabel(macro.name.isEmpty ? "Edit" : "Edit \(macro.name)") Button(action: onDelete) { Image(systemName: "trash") .foregroundColor(.red.opacity(0.8)) } .buttonStyle(.borderless) - .help("Delete") - .accessibilityLabel("Delete") + .help(macro.name.isEmpty ? "Delete" : "Delete \(macro.name)") + .accessibilityLabel(macro.name.isEmpty ? "Delete" : "Delete \(macro.name)") } } .padding(.horizontal, 12) diff --git a/XboxControllerMapper/XboxControllerMapper/Views/Scripts/ScriptListView.swift b/XboxControllerMapper/XboxControllerMapper/Views/Scripts/ScriptListView.swift index 40c6f5ff..e695f195 100644 --- a/XboxControllerMapper/XboxControllerMapper/Views/Scripts/ScriptListView.swift +++ b/XboxControllerMapper/XboxControllerMapper/Views/Scripts/ScriptListView.swift @@ -222,16 +222,16 @@ struct ScriptRow: View { .foregroundColor(.accentColor) } .buttonStyle(.borderless) - .help("Edit") - .accessibilityLabel("Edit") + .help(script.name.isEmpty ? "Edit" : "Edit \(script.name)") + .accessibilityLabel(script.name.isEmpty ? "Edit" : "Edit \(script.name)") Button(action: onDelete) { Image(systemName: "trash") .foregroundColor(.red.opacity(0.8)) } .buttonStyle(.borderless) - .help("Delete") - .accessibilityLabel("Delete") + .help(script.name.isEmpty ? "Delete" : "Delete \(script.name)") + .accessibilityLabel(script.name.isEmpty ? "Delete" : "Delete \(script.name)") } } .padding(.horizontal, 12)