From 6cdfc1f6a3a37329f6403e584e02d0d0dbcc09c1 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 25 Apr 2026 09:08:10 +0200 Subject: [PATCH] fix(bulk-upload): announce error chip status to screen readers The ! indicator was aria-hidden with no sr-only fallback, making failed uploads invisible to assistive technology. Added sr-only span with bulk_file_error_chip_label before the visual indicator. Co-Authored-By: Claude Sonnet 4.6 --- .../document/FileSwitcherStrip.svelte | 1 + .../document/FileSwitcherStrip.svelte.spec.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/frontend/src/lib/components/document/FileSwitcherStrip.svelte b/frontend/src/lib/components/document/FileSwitcherStrip.svelte index 5598fd42..d70241bc 100644 --- a/frontend/src/lib/components/document/FileSwitcherStrip.svelte +++ b/frontend/src/lib/components/document/FileSwitcherStrip.svelte @@ -103,6 +103,7 @@ $effect(() => { > {entry.title} {#if entry.status === 'error'} + {m.bulk_file_error_chip_label()} {/if} diff --git a/frontend/src/lib/components/document/FileSwitcherStrip.svelte.spec.ts b/frontend/src/lib/components/document/FileSwitcherStrip.svelte.spec.ts index bb069e86..6a6ccc83 100644 --- a/frontend/src/lib/components/document/FileSwitcherStrip.svelte.spec.ts +++ b/frontend/src/lib/components/document/FileSwitcherStrip.svelte.spec.ts @@ -78,6 +78,27 @@ describe('FileSwitcherStrip', () => { expect(errBtn).not.toBeNull(); }); + it('error chip contains a screen-reader-only error label', async () => { + const files: FileEntry[] = [ + { + id: 'e1', + file: new File([''], 'bad.pdf'), + title: 'Bad file', + status: 'error', + previewUrl: '' + } + ]; + const { container } = render(FileSwitcherStrip, { + files, + activeId: 'e1', + onSelect: vi.fn(), + onRemove: vi.fn() + }); + const errBtn = container.querySelector('[data-status="error"]'); + const srOnly = errBtn?.querySelector('.sr-only'); + expect(srOnly).not.toBeNull(); + }); + it('ArrowRight moves focus to next chip without leaving strip', async () => { const files = makeFiles(3); const { container } = render(FileSwitcherStrip, {