From 153752a901e2e43eaf81dc1af3e7b012b71032cf Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 8 May 2026 10:58:59 +0200 Subject: [PATCH] fix(documents): bump timeline control buttons to 44x44 (#385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WCAG 2.5.8 (target size, AA) requires 44×44 minimum, and the project's senior persona makes that a hard floor on desktop too. Reset-zoom: h-6 → h-11 + min-w-[44px] + px-3. Clear-selection: h-6 w-6 → h-11 w-11. Two regression tests on the TimelineDensityFilter spec assert the sized classes so a future shrink can't slip through silently. Co-Authored-By: Claude Sonnet 4.6 --- .../src/lib/document/TimelineControls.svelte | 4 ++-- .../TimelineDensityFilter.svelte.spec.ts | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/document/TimelineControls.svelte b/frontend/src/lib/document/TimelineControls.svelte index f33f69f5..401d9098 100644 --- a/frontend/src/lib/document/TimelineControls.svelte +++ b/frontend/src/lib/document/TimelineControls.svelte @@ -22,7 +22,7 @@ let { aria-label={m.timeline_zoom_reset()} title={m.timeline_zoom_reset()} onclick={onresetzoom} - class="hover:text-ink-1 inline-flex h-6 items-center justify-center gap-1 rounded-sm px-2 text-xs text-ink-3 hover:bg-canvas" + class="hover:text-ink-1 inline-flex h-11 min-w-[44px] items-center justify-center gap-1 rounded-sm px-3 text-xs text-ink-3 hover:bg-canvas" > ↩ @@ -33,7 +33,7 @@ let { data-testid="timeline-clear" aria-label={m.timeline_clear_selection()} onclick={onclearselection} - class="hover:text-ink-1 inline-flex h-6 w-6 items-center justify-center rounded-full text-ink-3 hover:bg-canvas" + class="hover:text-ink-1 inline-flex h-11 w-11 items-center justify-center rounded-full text-ink-3 hover:bg-canvas" > × diff --git a/frontend/src/lib/document/TimelineDensityFilter.svelte.spec.ts b/frontend/src/lib/document/TimelineDensityFilter.svelte.spec.ts index cff9180e..aaa7de58 100644 --- a/frontend/src/lib/document/TimelineDensityFilter.svelte.spec.ts +++ b/frontend/src/lib/document/TimelineDensityFilter.svelte.spec.ts @@ -308,6 +308,24 @@ describe('TimelineDensityFilter — zoom', () => { }); }); +describe('TimelineDensityFilter — touch targets', () => { + it('reset-zoom button is at least 44×44 (WCAG 2.5.8)', async () => { + render(TimelineDensityFilter, makeProps({ zoomFrom: '1915-08-01', zoomTo: '1915-09-30' })); + const resetBtn = document.querySelector('[data-testid="timeline-zoom-reset"]') as HTMLElement; + expect(resetBtn.classList.contains('h-11')).toBe(true); + expect(resetBtn.className).toMatch(/min-w-\[44px\]/); + expect(resetBtn.className).not.toMatch(/(?:^|\s)h-6(?:$|\s)/); + }); + + it('clear-selection button is at least 44×44 (WCAG 2.5.8)', async () => { + render(TimelineDensityFilter, makeProps({ from: '1915-08-01', to: '1915-09-30' })); + const clearBtn = document.querySelector('[data-testid="timeline-clear"]') as HTMLElement; + expect(clearBtn.classList.contains('h-11')).toBe(true); + expect(clearBtn.classList.contains('w-11')).toBe(true); + expect(clearBtn.className).not.toMatch(/(?:^|\s)h-6(?:$|\s)/); + }); +}); + describe('TimelineDensityFilter — accessibility', () => { it('Y-axis labels meet the 12px minimum font floor (Tailwind text-xs)', async () => { render(TimelineDensityFilter, makeProps());