fix(timeline): label the cross-year ✉ glyph for screen readers
The cross-year card header emitted a bare aria-hidden ✉ with no sr-only label, unlike the same-year header and LetterCard — a screen-reader user heard only the title with no cue that this is a letter group. It now uses the shared GlyphLabel (✉ + sr-only "Brief"). Fixes review finding #6 (glyph half). Refs #850 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as m from '$lib/paraglide/messages.js';
|
import * as m from '$lib/paraglide/messages.js';
|
||||||
import LetterCard from './LetterCard.svelte';
|
import LetterCard from './LetterCard.svelte';
|
||||||
|
import GlyphLabel from './GlyphLabel.svelte';
|
||||||
import { entryKey } from './entryKey';
|
import { entryKey } from './entryKey';
|
||||||
import { getAccentConfig } from './eventCardConfig';
|
import { getAccentConfig } from './eventCardConfig';
|
||||||
import { timelineDateLabel } from './dateLabel';
|
import { timelineDateLabel } from './dateLabel';
|
||||||
@@ -107,7 +108,7 @@ const hiddenCount = $derived(letters.length - CLUSTER_PREVIEW);
|
|||||||
class="flex items-center gap-2 border-b border-line px-3 py-2"
|
class="flex items-center gap-2 border-b border-line px-3 py-2"
|
||||||
>
|
>
|
||||||
<span class="font-serif text-sm font-bold whitespace-pre-line text-ink">
|
<span class="font-serif text-sm font-bold whitespace-pre-line text-ink">
|
||||||
<span aria-hidden="true">✉</span>
|
<GlyphLabel glyph="✉" label={m.timeline_letter_glyph_label()} />
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
<span data-testid="event-count" class="font-sans text-xs text-ink-3">· {count}</span>
|
<span data-testid="event-count" class="font-sans text-xs text-ink-3">· {count}</span>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { describe, it, expect, afterEach } from 'vitest';
|
import { describe, it, expect, afterEach } from 'vitest';
|
||||||
import { cleanup, render } from 'vitest-browser-svelte';
|
import { cleanup, render } from 'vitest-browser-svelte';
|
||||||
import { tick } from 'svelte';
|
import { tick } from 'svelte';
|
||||||
|
import * as m from '$lib/paraglide/messages.js';
|
||||||
import EventCluster from './EventCluster.svelte';
|
import EventCluster from './EventCluster.svelte';
|
||||||
import { makeEntry } from './test-factories';
|
import { makeEntry } from './test-factories';
|
||||||
import type { components } from '$lib/generated/api';
|
import type { components } from '$lib/generated/api';
|
||||||
@@ -98,6 +99,15 @@ describe('EventCluster — contained event card (#850)', () => {
|
|||||||
expect(document.querySelector('[data-testid="event-edit"]')).toBeNull();
|
expect(document.querySelector('[data-testid="event-edit"]')).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('pairs the cross-year ✉ glyph with an sr-only label so it is not a silent glyph (finding #6)', () => {
|
||||||
|
render(EventCluster, { letters: letters(2), title: 'Briefe von der Front' });
|
||||||
|
const header = document.querySelector('[data-testid="event-header"]') as HTMLElement;
|
||||||
|
const hidden = header.querySelector('[aria-hidden="true"]');
|
||||||
|
expect(hidden?.textContent).toContain('✉');
|
||||||
|
const srOnly = header.querySelector('.sr-only');
|
||||||
|
expect(srOnly?.textContent).toBe(m.timeline_letter_glyph_label());
|
||||||
|
});
|
||||||
|
|
||||||
it('renders an HTML-bearing event title verbatim as text, never as markup (REQ-010)', () => {
|
it('renders an HTML-bearing event title verbatim as text, never as markup (REQ-010)', () => {
|
||||||
render(EventCluster, {
|
render(EventCluster, {
|
||||||
letters: letters(1),
|
letters: letters(1),
|
||||||
|
|||||||
Reference in New Issue
Block a user