fix(documents): pluralise timeline bar aria-label by count (#385)
The flat "{count} Dokumente / documents / documentos" keys read as
"1 Dokumente" / "1 documents" / "1 documentos" to a screen reader
when only one document falls in the month bucket. Splits each
locale into _singular + _plural keys and picks the form by count
in TimelineBars, mirroring the existing upload_banner_singular /
_plural pattern in this project.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1050,6 +1050,7 @@
|
||||
"timeline_aria_label": "Zeitachse Dokumentdichte",
|
||||
"timeline_clear_selection": "Auswahl zurücksetzen",
|
||||
"timeline_zoom_reset": "Zurück zur Übersicht",
|
||||
"timeline_bar_aria": "{when}, {count} Dokumente",
|
||||
"timeline_bar_aria_singular": "{when}, 1 Dokument",
|
||||
"timeline_bar_aria_plural": "{when}, {count} Dokumente",
|
||||
"timeline_dragging_aria_live": "Zeitraum {from} bis {to} ausgewählt"
|
||||
}
|
||||
|
||||
@@ -1050,6 +1050,7 @@
|
||||
"timeline_aria_label": "Document density timeline",
|
||||
"timeline_clear_selection": "Clear selection",
|
||||
"timeline_zoom_reset": "Reset zoom",
|
||||
"timeline_bar_aria": "{when}, {count} documents",
|
||||
"timeline_bar_aria_singular": "{when}, 1 document",
|
||||
"timeline_bar_aria_plural": "{when}, {count} documents",
|
||||
"timeline_dragging_aria_live": "Range {from} to {to} selected"
|
||||
}
|
||||
|
||||
@@ -1050,6 +1050,7 @@
|
||||
"timeline_aria_label": "Cronología de densidad de documentos",
|
||||
"timeline_clear_selection": "Borrar selección",
|
||||
"timeline_zoom_reset": "Restablecer zoom",
|
||||
"timeline_bar_aria": "{when}, {count} documentos",
|
||||
"timeline_bar_aria_singular": "{when}, 1 documento",
|
||||
"timeline_bar_aria_plural": "{when}, {count} documentos",
|
||||
"timeline_dragging_aria_live": "Rango {from} a {to} seleccionado"
|
||||
}
|
||||
|
||||
@@ -51,10 +51,12 @@ function barHeight(count: number): number {
|
||||
<button
|
||||
type="button"
|
||||
data-testid="timeline-bar"
|
||||
aria-label={m.timeline_bar_aria({
|
||||
when: formatTickLabel(bucket.month, getLocale()),
|
||||
count: bucket.count
|
||||
})}
|
||||
aria-label={bucket.count === 1
|
||||
? m.timeline_bar_aria_singular({ when: formatTickLabel(bucket.month, getLocale()) })
|
||||
: m.timeline_bar_aria_plural({
|
||||
when: formatTickLabel(bucket.month, getLocale()),
|
||||
count: bucket.count
|
||||
})}
|
||||
aria-pressed={isSelected(bucket.month)}
|
||||
onpointerdown={(e) => onbarpointerdown(e, i)}
|
||||
onpointerenter={() => onbarpointerenter(i)}
|
||||
|
||||
@@ -350,6 +350,36 @@ describe('TimelineDensityFilter — accessibility', () => {
|
||||
expect(xAxis.className).not.toMatch(/text-\[10px\]/);
|
||||
});
|
||||
|
||||
it('bar aria-label uses the singular noun form when count is 1', async () => {
|
||||
render(
|
||||
TimelineDensityFilter,
|
||||
makeProps({
|
||||
density: [{ month: '1915-08', count: 1 }],
|
||||
minDate: '1915-08-01',
|
||||
maxDate: '1915-08-31'
|
||||
})
|
||||
);
|
||||
const bar = document.querySelector('[data-testid="timeline-bar"]') as HTMLElement;
|
||||
const label = bar.getAttribute('aria-label') ?? '';
|
||||
// "documents", "Dokumente", "documentos" are the plural-only forms in our 3 locales.
|
||||
expect(label).not.toMatch(/\b(?:documents|Dokumente|documentos)\b/);
|
||||
expect(label).toMatch(/\b1 (?:document|Dokument|documento)\b/);
|
||||
});
|
||||
|
||||
it('bar aria-label uses the plural noun form when count is not 1', async () => {
|
||||
render(
|
||||
TimelineDensityFilter,
|
||||
makeProps({
|
||||
density: [{ month: '1915-08', count: 5 }],
|
||||
minDate: '1915-08-01',
|
||||
maxDate: '1915-08-31'
|
||||
})
|
||||
);
|
||||
const bar = document.querySelector('[data-testid="timeline-bar"]') as HTMLElement;
|
||||
const label = bar.getAttribute('aria-label') ?? '';
|
||||
expect(label).toMatch(/\b5 (?:documents|Dokumente|documentos)\b/);
|
||||
});
|
||||
|
||||
it('bar aria-label is built from a localised template, never the raw YYYY-MM', async () => {
|
||||
render(
|
||||
TimelineDensityFilter,
|
||||
|
||||
Reference in New Issue
Block a user