@@ -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