Skip to content

Commit f40544f

Browse files
fix(a11y): Add aria-label attributes to form controls
- Add aria-label prop support to SearchInput component - Add aria-label attributes to DatasetPanel form controls (size slider, inputs, select) - Add aria-label to SearchInput instances in HomePage and FilterBar - Add aria-label to search target input in VisualizerPage - Fix accessibility violations detected by pa11y-ci in GitHub Actions Fixes #accessibility-violations
1 parent 4ba8e7b commit f40544f

File tree

5 files changed

+27
-0
lines changed

5 files changed

+27
-0
lines changed

src/components/controls/DatasetPanel.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ export default function DatasetPanel({ value, onChange }: Props) {
261261
value={n}
262262
onChange={(e) => setN(Number(e.target.value))}
263263
className="w-full"
264+
aria-label={t("controls.size", { defaultValue: "Size" })}
264265
/>
265266
<input
266267
type="number"
@@ -269,6 +270,9 @@ export default function DatasetPanel({ value, onChange }: Props) {
269270
value={n}
270271
onChange={(e) => setN(Number(e.target.value))}
271272
className="ui-input w-16 shrink-0"
273+
aria-label={
274+
t("controls.size", { defaultValue: "Size" }) + " value"
275+
}
272276
/>
273277
</div>
274278

@@ -282,13 +286,19 @@ export default function DatasetPanel({ value, onChange }: Props) {
282286
value={min}
283287
onChange={(e) => setMin(Number(e.target.value))}
284288
className="ui-input w-16 shrink-0"
289+
aria-label={
290+
t("controls.range", { defaultValue: "Range" }) + " minimum"
291+
}
285292
/>
286293
<span className="panel-muted shrink-0">to</span>
287294
<input
288295
type="number"
289296
value={max}
290297
onChange={(e) => setMax(Number(e.target.value))}
291298
className="ui-input w-16 shrink-0"
299+
aria-label={
300+
t("controls.range", { defaultValue: "Range" }) + " maximum"
301+
}
292302
/>
293303
</label>
294304

@@ -302,6 +312,7 @@ export default function DatasetPanel({ value, onChange }: Props) {
302312
value={seed}
303313
onChange={(e) => setSeed(Number(e.target.value))}
304314
className="ui-input w-28 shrink-0"
315+
aria-label={t("controls.seed", { defaultValue: "Seed" })}
305316
/>
306317
</label>
307318

@@ -340,6 +351,7 @@ export default function DatasetPanel({ value, onChange }: Props) {
340351
value={dist}
341352
onChange={(e) => setDist(e.target.value as Dist)}
342353
className="ui-select w-full"
354+
aria-label="Distribution type"
343355
>
344356
<optgroup
345357
label={t("controls.distributions.basic", {
@@ -441,6 +453,7 @@ export default function DatasetPanel({ value, onChange }: Props) {
441453
value={uniques}
442454
onChange={(e) => setUniques(Number(e.target.value))}
443455
className="ui-input w-16 shrink-0"
456+
aria-label={t("controls.uniques", { defaultValue: "Uniques" })}
444457
/>
445458
</label>
446459
)}
@@ -456,6 +469,7 @@ export default function DatasetPanel({ value, onChange }: Props) {
456469
value={period}
457470
onChange={(e) => setPeriod(Number(e.target.value))}
458471
className="ui-input w-16 shrink-0"
472+
aria-label={t("controls.period", { defaultValue: "Period" })}
459473
/>
460474
</label>
461475
)}
@@ -485,6 +499,9 @@ export default function DatasetPanel({ value, onChange }: Props) {
485499
})}
486500
value={customText}
487501
onChange={onCustomChange}
502+
aria-label={t("controls.customNumbers", {
503+
defaultValue: "Custom numbers",
504+
})}
488505
/>
489506
</div>
490507
)}

src/components/home/FilterBar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export default function FilterBar(props: Props) {
113113
defaultValue:
114114
"Search by algorithm, tags, concepts, or difficulty...",
115115
})}
116+
aria-label="Search algorithms by name, tags, concepts, or difficulty"
116117
// Performance optimization for fast typing
117118
debounceMs={20}
118119
// Enhanced search props

src/components/ui/SearchInput.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export interface SearchInputProps {
4444
loading?: boolean;
4545
disabled?: boolean;
4646
autoFocus?: boolean;
47+
48+
// Accessibility props
49+
"aria-label"?: string;
4750
}
4851

4952
export function SearchInput({
@@ -73,6 +76,9 @@ export function SearchInput({
7376
loading = false,
7477
disabled = false,
7578
autoFocus = false,
79+
80+
// Accessibility props
81+
"aria-label": ariaLabel,
7682
}: SearchInputProps) {
7783
const [internalValue, setInternalValue] = useState(value);
7884
const [showDropdown, setShowDropdown] = useState(false);
@@ -349,6 +355,7 @@ export function SearchInput({
349355
}}
350356
disabled={disabled}
351357
loading={loading || isSearching}
358+
aria-label={ariaLabel}
352359
leftIcon={
353360
<svg
354361
className="h-4 w-4"

src/pages/HomePage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ export default function HomePage() {
837837
onChange={(value) => setQ(value)}
838838
placeholder="Quick search..."
839839
className="w-48 text-sm"
840+
aria-label="Quick search algorithms"
840841
// Enable dropdown with algorithm suggestions
841842
searchableItems={searchableItems}
842843
enableFuzzySearch={true}

src/pages/VisualizerPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ export default function VisualizerPage() {
627627
max={99}
628628
placeholder="Enter target value"
629629
title="Target value to search for"
630+
aria-label="Search target value"
630631
/>
631632
{meta.slug === "binary-search" && (
632633
<p

0 commit comments

Comments
 (0)