fix(a11y): increase all PdfControls buttons to 44×44px touch targets
Add min-h-[44px] min-w-[44px] to all five PDF viewer buttons (prev, next, zoom in, zoom out, annotation toggle) and widen icon-only padding from p-1 to p-2. Adds aria-pressed to the annotation toggle for correct toggle semantics (WCAG 2.2 §2.5.8 + ARIA 1.2). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -65,3 +65,82 @@ describe('PdfControls — annotation toggle contrast (WCAG 2.1 AA)', () => {
|
||||
expect(annotationBtn!.className).not.toContain('text-accent');
|
||||
});
|
||||
});
|
||||
|
||||
describe('PdfControls — touch targets (WCAG 2.2 §2.5.8)', () => {
|
||||
it('annotation toggle button has min-h-[44px] touch target', async () => {
|
||||
const { container } = render(PdfControls, {
|
||||
...defaultProps,
|
||||
annotationCount: 2,
|
||||
showAnnotations: false
|
||||
});
|
||||
const allButtons = container.querySelectorAll('button');
|
||||
const annotationBtn = Array.from(allButtons).find((b) =>
|
||||
b.getAttribute('aria-label')?.toLowerCase().includes('annotierungen')
|
||||
);
|
||||
expect(annotationBtn).not.toBeNull();
|
||||
expect(annotationBtn!.className).toContain('min-h-[44px]');
|
||||
});
|
||||
|
||||
it('annotation toggle button has min-w-[44px] touch target', async () => {
|
||||
const { container } = render(PdfControls, {
|
||||
...defaultProps,
|
||||
annotationCount: 2,
|
||||
showAnnotations: false
|
||||
});
|
||||
const allButtons = container.querySelectorAll('button');
|
||||
const annotationBtn = Array.from(allButtons).find((b) =>
|
||||
b.getAttribute('aria-label')?.toLowerCase().includes('annotierungen')
|
||||
);
|
||||
expect(annotationBtn).not.toBeNull();
|
||||
expect(annotationBtn!.className).toContain('min-w-[44px]');
|
||||
});
|
||||
|
||||
it('annotation toggle reflects pressed state via aria-pressed', async () => {
|
||||
const { container: c1 } = render(PdfControls, {
|
||||
...defaultProps,
|
||||
annotationCount: 2,
|
||||
showAnnotations: false
|
||||
});
|
||||
const btn1 = Array.from(c1.querySelectorAll('button')).find((b) =>
|
||||
b.getAttribute('aria-label')?.toLowerCase().includes('annotierungen')
|
||||
);
|
||||
expect(btn1!.getAttribute('aria-pressed')).toBe('false');
|
||||
cleanup();
|
||||
|
||||
const { container: c2 } = render(PdfControls, {
|
||||
...defaultProps,
|
||||
annotationCount: 2,
|
||||
showAnnotations: true
|
||||
});
|
||||
const btn2 = Array.from(c2.querySelectorAll('button')).find((b) =>
|
||||
b.getAttribute('aria-label')?.toLowerCase().includes('annotierungen')
|
||||
);
|
||||
expect(btn2!.getAttribute('aria-pressed')).toBe('true');
|
||||
});
|
||||
|
||||
it('icon-only nav/zoom buttons each have min-h-[44px] touch target', async () => {
|
||||
const { container } = render(PdfControls, { ...defaultProps });
|
||||
const allButtons = container.querySelectorAll('button');
|
||||
const iconOnlyButtons = Array.from(allButtons).filter((b) => {
|
||||
const label = b.getAttribute('aria-label') ?? '';
|
||||
return ['zurück', 'weiter', 'verkleinern', 'vergrößern'].includes(label.toLowerCase());
|
||||
});
|
||||
expect(iconOnlyButtons).toHaveLength(4);
|
||||
for (const btn of iconOnlyButtons) {
|
||||
expect(btn.className).toContain('min-h-[44px]');
|
||||
}
|
||||
});
|
||||
|
||||
it('icon-only nav/zoom buttons each have min-w-[44px] touch target', async () => {
|
||||
const { container } = render(PdfControls, { ...defaultProps });
|
||||
const allButtons = container.querySelectorAll('button');
|
||||
const iconOnlyButtons = Array.from(allButtons).filter((b) => {
|
||||
const label = b.getAttribute('aria-label') ?? '';
|
||||
return ['zurück', 'weiter', 'verkleinern', 'vergrößern'].includes(label.toLowerCase());
|
||||
});
|
||||
expect(iconOnlyButtons).toHaveLength(4);
|
||||
for (const btn of iconOnlyButtons) {
|
||||
expect(btn.className).toContain('min-w-[44px]');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user