Skip to content

Commit bfa73d9

Browse files
Merge pull request #324 into main
2 parents 88f2ecd + 1aeee0e commit bfa73d9

2 files changed

Lines changed: 50 additions & 36 deletions

File tree

.jules/palette.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@
77
## 2024-06-25 - Focus and hover colors for Glass widgets
88
**Learning:** Glassmorphism UI elements using `Colors.white.withValues(alpha: opacity)` for their background can mask default `InkWell` keyboard focus and mouse hover states.
99
**Action:** Always explicitly define `focusColor` and `hoverColor` (e.g. `Colors.white.withValues(alpha: 0.1)`) on `InkWell` components used within glassmorphism widgets to maintain accessibility for keyboard and mouse users.
10+
11+
## 2024-09-02 - Add Semantic Button traits to custom filter pills
12+
**Learning:** Filter chips built with AnimatedContainer and GestureDetector lack standard button semantics and keyboard focus states, making them inaccessible.
13+
**Action:** Replace GestureDetector with InkWell inside a Semantics(button: true) wrapper to explicitly add button traits, and define hoverColor/focusColor to ensure keyboard accessibility.

lib/views/explore/explore_view.dart

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -193,43 +193,53 @@ class _ExploreViewState extends State<ExploreView> {
193193
final isSelected = category == _selectedCategory;
194194
return Padding(
195195
padding: const EdgeInsets.only(right: 8),
196-
child: GestureDetector(
197-
onTap: () {
198-
setState(() => _selectedCategory = category);
199-
_filterContent();
200-
},
201-
child: AnimatedContainer(
202-
duration: const Duration(milliseconds: 200),
203-
padding: const EdgeInsets.symmetric(
204-
horizontal: 18,
205-
vertical: 8,
206-
),
207-
decoration: BoxDecoration(
208-
gradient: isSelected
209-
? AppTheme.primaryGradient
210-
: null,
211-
color: isSelected
212-
? null
213-
: Colors.white.withValues(alpha: 0.08),
196+
child: Semantics(
197+
button: true,
198+
enabled: true,
199+
child: Material(
200+
color: Colors.transparent,
201+
child: InkWell(
202+
focusColor: Colors.white.withValues(alpha: 0.1),
203+
hoverColor: Colors.white.withValues(alpha: 0.1),
214204
borderRadius: BorderRadius.circular(20),
215-
border: isSelected
216-
? null
217-
: Border.all(
218-
color: Colors.white.withValues(
219-
alpha: 0.1,
220-
),
221-
),
222-
),
223-
child: Text(
224-
category,
225-
style: TextStyle(
226-
color: isSelected
227-
? Colors.white
228-
: AppTheme.textSecondary,
229-
fontWeight: isSelected
230-
? FontWeight.w600
231-
: FontWeight.w500,
232-
fontSize: 14,
205+
onTap: () {
206+
setState(() => _selectedCategory = category);
207+
_filterContent();
208+
},
209+
child: AnimatedContainer(
210+
duration: const Duration(milliseconds: 200),
211+
padding: const EdgeInsets.symmetric(
212+
horizontal: 18,
213+
vertical: 8,
214+
),
215+
decoration: BoxDecoration(
216+
gradient: isSelected
217+
? AppTheme.primaryGradient
218+
: null,
219+
color: isSelected
220+
? null
221+
: Colors.white.withValues(alpha: 0.08),
222+
borderRadius: BorderRadius.circular(20),
223+
border: isSelected
224+
? null
225+
: Border.all(
226+
color: Colors.white.withValues(
227+
alpha: 0.1,
228+
),
229+
),
230+
),
231+
child: Text(
232+
category,
233+
style: TextStyle(
234+
color: isSelected
235+
? Colors.white
236+
: AppTheme.textSecondary,
237+
fontWeight: isSelected
238+
? FontWeight.w600
239+
: FontWeight.w500,
240+
fontSize: 14,
241+
),
242+
),
233243
),
234244
),
235245
),

0 commit comments

Comments
 (0)