Skip to content

Commit a63e256

Browse files
committed
Update the active filter button behavior
Tapping on the active filter now shows the filter list. To reset the active filter, the user must tap on the Close icon. In addition, this also improves accessibility: * The active filter button now separates between the Close button and the active filter button, since they are now different. * Added an accessibility hint for the active filter to inform the user that tapping the active filter will open the filter list. * Added an accessibility label for the Search icon button.
1 parent 35332e8 commit a63e256

1 file changed

Lines changed: 66 additions & 23 deletions

File tree

WordPress/Classes/ViewRelated/Reader/Tab Navigation/ReaderNavigationMenu.swift

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,45 +51,50 @@ struct ReaderNavigationMenu: View {
5151
Image(uiImage: .gridicon(.search)
5252
.withRenderingMode(.alwaysTemplate))
5353
.foregroundStyle(Colors.searchIcon)
54+
.padding(4.0)
5455
}
56+
.accessibilityLabel(Text(Strings.searchFilterAccessibilityLabel))
5557
}
5658
}
5759

5860
@ViewBuilder
5961
var streamFilterView: some View {
6062
ForEach(filters) { filter in
61-
Button {
62-
if hasActiveFilter {
63-
viewModel.resetStreamFilter()
64-
} else {
65-
viewModel.didTapStreamFilterButton(with: filter)
66-
}
67-
} label: {
68-
streamFilterChip(title: viewModel.activeStreamFilter?.topic.title ?? filter.title, isSelected: hasActiveFilter)
69-
}
70-
.transition(
71-
.asymmetric(insertion: .slide, removal: .move(edge: .leading))
72-
.combined(with: .opacity)
73-
)
63+
streamFilterChip(filter: filter, isSelected: hasActiveFilter)
64+
.transition(
65+
.asymmetric(insertion: .slide, removal: .move(edge: .leading))
66+
.combined(with: .opacity)
67+
)
7468
}
7569
}
7670

7771
@ViewBuilder
78-
func streamFilterChip(title: String, isSelected: Bool = false) -> some View {
72+
func streamFilterChip(filter: FilterProvider, isSelected: Bool) -> some View {
7973
HStack(alignment: .center, spacing: 8.0) {
80-
Text(title)
81-
.font(.subheadline)
82-
.fontWeight(.semibold)
83-
.foregroundStyle(isSelected ? Colors.StreamFilter.selectedText : Colors.StreamFilter.text)
74+
Button {
75+
viewModel.didTapStreamFilterButton(with: filter)
76+
} label: {
77+
Text(viewModel.activeStreamFilter?.topic.title ?? filter.title)
78+
.font(.subheadline)
79+
.fontWeight(.semibold)
80+
.foregroundStyle(isSelected ? Colors.StreamFilter.selectedText : Colors.StreamFilter.text)
81+
}
82+
.accessibilityLabel(Text(filterAccessibilityLabel(for: filter)))
83+
.accessibilityHint(Text(isSelected ? Strings.activeFilterAccessibilityHint : String()))
8484

8585
if isSelected {
86-
Image("reader-menu-close")
87-
.frame(width: 24.0, height: 24.0)
88-
.foregroundStyle(Colors.StreamFilter.selectedText)
86+
Button {
87+
withAnimation(.easeInOut) {
88+
viewModel.resetStreamFilter()
89+
}
90+
} label: {
91+
Image("reader-menu-close")
92+
.frame(width: 24.0, height: 24.0)
93+
.foregroundStyle(Colors.StreamFilter.selectedText)
94+
}
95+
.accessibilityLabel(Text(Strings.resetFilterAccessibilityLabel))
8996
}
9097
}
91-
// the inherent padding from the close image bumps the content height, so we'll need to reduce the padding
92-
// when the close button is shown.
9398
.padding(.vertical, 6.0)
9499
.padding(.leading, 16.0)
95100
.padding(.trailing, isSelected ? 8.0 : 16.0)
@@ -98,6 +103,13 @@ struct ReaderNavigationMenu: View {
98103
.clipShape(Capsule())
99104
}
100105

106+
private func filterAccessibilityLabel(for filter: FilterProvider) -> String {
107+
guard let activeFilter = viewModel.activeStreamFilter else {
108+
return filter.title
109+
}
110+
return String(format: Strings.activeFilterAccessibilityStringFormat, activeFilter.topic.title)
111+
}
112+
101113
struct Colors {
102114
static let searchIcon: Color = Color(uiColor: .text)
103115

@@ -109,4 +121,35 @@ struct ReaderNavigationMenu: View {
109121
}
110122
}
111123

124+
struct Strings {
125+
static let activeFilterAccessibilityStringFormat = NSLocalizedString(
126+
"reader.navigation.menu.activeFilter.a11y.label",
127+
value: "Filtered by %1$@",
128+
comment: """
129+
Accessibility label for when the user has an active filter.
130+
This informs the user that the currently displayed stream is being filtered.
131+
"""
132+
)
133+
134+
static let activeFilterAccessibilityHint = NSLocalizedString(
135+
"reader.navigation.menu.filter.a11y.hint",
136+
value: "Opens the filter list",
137+
comment: """
138+
Accessibility hint that informs the user that the filter list will be opened when they interact
139+
with the filter chip button.
140+
"""
141+
)
142+
143+
static let resetFilterAccessibilityLabel = NSLocalizedString(
144+
"reader.navigation.menu.reset.a11y.label",
145+
value: "Reset",
146+
comment: "Accessibility label for the Close icon button, to reset the active filter."
147+
)
148+
149+
static let searchFilterAccessibilityLabel = NSLocalizedString(
150+
"reader.navigation.menu.search.a11y.label",
151+
value: "Search",
152+
comment: "Accessibility label for the Search icon."
153+
)
154+
}
112155
}

0 commit comments

Comments
 (0)