diff --git a/frontend/src/lib/components/ThumbnailRow.svelte b/frontend/src/lib/components/ThumbnailRow.svelte index ef9a8ccb..50de4609 100644 --- a/frontend/src/lib/components/ThumbnailRow.svelte +++ b/frontend/src/lib/components/ThumbnailRow.svelte @@ -50,8 +50,9 @@ const relativeYearLabel = $derived( ? relativeYearsDe(new Date(doc.documentDate + 'T12:00:00'), now ?? new Date()) : '' ); +const directionLabel = $derived(isOut ? 'Gesendet' : 'Empfangen'); const ariaLabel = $derived( - `${title}${doc.documentDate ? `, ${formatDate(doc.documentDate)}` : ''}` + `${directionLabel}: ${title}${doc.documentDate ? `, ${formatDate(doc.documentDate)}` : ''}` ); diff --git a/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts b/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts index e3c6572d..ae0542e1 100644 --- a/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts +++ b/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts @@ -127,7 +127,7 @@ describe('ThumbnailRow', () => { expect(link.className).toContain('border-l-accent'); }); - it('exposes a descriptive aria-label combining title and date', () => { + it('exposes a descriptive aria-label combining direction, title, and date', () => { render(ThumbnailRow, { doc: baseDoc, isOut: true, @@ -137,10 +137,23 @@ describe('ThumbnailRow', () => { const link = document.querySelector('a[href="/documents/d1"]') as HTMLElement; const label = link.getAttribute('aria-label') ?? ''; + expect(label).toMatch(/^Gesendet:/); expect(label).toContain('Liebe Anna'); expect(label).toMatch(/1950/); }); + it('aria-label begins with "Empfangen:" for incoming letters', () => { + render(ThumbnailRow, { + doc: baseDoc, + isOut: false, + showOtherParty: false, + now: new Date('2026-06-01T00:00:00Z') + }); + + const link = document.querySelector('a[href="/documents/d1"]') as HTMLElement; + expect(link.getAttribute('aria-label') ?? '').toMatch(/^Empfangen:/); + }); + it('does not inject raw HTML when summary contains markup (XSS regression)', () => { render(ThumbnailRow, { doc: {