From 8e0b447d8f4edaca6d93457d5cd65e07a7a3e393 Mon Sep 17 00:00:00 2001
From: Linus Rath <139418639+rathlinus@users.noreply.github.com>
Date: Sat, 31 Oct 2026 13:32:21 +0100
Subject: [PATCH] fix: name the month button by its month and the participant
remove button by the person
---
locales/rn/de.json | 6 +++--
locales/rn/en.json | 4 ++-
src/components/calendar/ParticipantInput.tsx | 3 ++-
src/lib/__tests__/calendar-a11y.test.ts | 28 +++++++++++++++++++-
src/lib/calendar-a11y.ts | 14 ++++++++++
src/screens/CalendarScreen.tsx | 3 ++-
6 files changed, 52 insertions(+), 6 deletions(-)
diff --git a/locales/rn/de.json b/locales/rn/de.json
index 7ea5fb1f..0632ec64 100644
--- a/locales/rn/de.json
+++ b/locales/rn/de.json
@@ -93,7 +93,8 @@
},
"occurrence_not_found_again": "Die Änderung wurde nicht gespeichert: Der Termin konnte auf dem Server nicht wiedergefunden werden. Versuchen Sie es erneut.",
"participants": {
- "limit_warning": "Mehr als {max, plural, one {# Teilnehmer} other {# Teilnehmer}}, den Organisator mitgezählt: Der Server lehnt das Speichern dieses Termins möglicherweise ab. Ihr Administrator kann das Limit erhöhen."
+ "limit_warning": "Mehr als {max, plural, one {# Teilnehmer} other {# Teilnehmer}}, den Organisator mitgezählt: Der Server lehnt das Speichern dieses Termins möglicherweise ab. Ihr Administrator kann das Limit erhöhen.",
+ "remove_named": "{name} entfernen"
},
"recurrence": {
"editor_occurrences_count": "{count, plural, one {Termin} other {Terminen}}",
@@ -148,7 +149,8 @@
},
"detail": {
"delete_confirm": "Dieses Ereignis löschen?"
- }
+ },
+ "change_month_named": "{month}, Monat wechseln"
},
"common": {
"add": "Hinzufügen",
diff --git a/locales/rn/en.json b/locales/rn/en.json
index 04385b69..176c2bf2 100644
--- a/locales/rn/en.json
+++ b/locales/rn/en.json
@@ -13,6 +13,7 @@
"alerts": {
"minutes_after": "{count, plural, one {# minute after} other {# minutes after}}"
},
+ "change_month_named": "{month}, change month",
"colors": {
"indigo": "Indigo",
"teal": "Teal"
@@ -116,7 +117,8 @@
"occurrence_not_found_again": "The change was not saved: the occurrence could not be found again on the server. Please try again.",
"participants": {
"group_members": "{count, plural, one {# member} other {# members}}",
- "limit_warning": "More than {max, plural, one {# participant} other {# participants}}, including the organizer: the server may refuse to save this event. An administrator can raise the limit."
+ "limit_warning": "More than {max, plural, one {# participant} other {# participants}}, including the organizer: the server may refuse to save this event. An administrator can raise the limit.",
+ "remove_named": "Remove {name}"
},
"recurrence": {
"editor_occurrences_count": "{count, plural, one {occurrence} other {occurrences}}",
diff --git a/src/components/calendar/ParticipantInput.tsx b/src/components/calendar/ParticipantInput.tsx
index 6cfe8f5e..55d56359 100644
--- a/src/components/calendar/ParticipantInput.tsx
+++ b/src/components/calendar/ParticipantInput.tsx
@@ -14,6 +14,7 @@ import { useContactsStore, type RecipientSuggestion } from '../../stores/contact
import { useLocaleStore } from '../../stores/locale-store';
import type { Attendee } from '../../lib/calendar-participants';
import { participantSuggestions, participantsFromSuggestion } from '../../lib/calendar-participant-suggestions';
+import { participantRemoveAccessibilityLabel } from '../../lib/calendar-a11y';
interface ParticipantInputProps {
attendees: Attendee[];
@@ -92,7 +93,7 @@ export function ParticipantInput({ attendees, onAdd, onRemove }: ParticipantInpu
onPress={() => onRemove(a.email)}
hitSlop={6}
accessibilityRole="button"
- accessibilityLabel={t('calendar.participants.remove', 'Remove')}
+ accessibilityLabel={participantRemoveAccessibilityLabel(a, t)}
>
diff --git a/src/lib/__tests__/calendar-a11y.test.ts b/src/lib/__tests__/calendar-a11y.test.ts
index 413a9156..23f25d68 100644
--- a/src/lib/__tests__/calendar-a11y.test.ts
+++ b/src/lib/__tests__/calendar-a11y.test.ts
@@ -7,7 +7,12 @@ vi.hoisted(() => {
import { enUS } from 'date-fns/locale';
import type { CalendarEvent } from '../../api/types';
import { formatMessage } from '../../i18n/format';
-import { dayCellAccessibilityLabel, eventAccessibilityLabel } from '../calendar-a11y';
+import {
+ dayCellAccessibilityLabel,
+ eventAccessibilityLabel,
+ monthButtonAccessibilityLabel,
+ participantRemoveAccessibilityLabel,
+} from '../calendar-a11y';
import { useSettingsStore } from '../../stores/settings-store';
const t = (_key: string, fallback?: string, params?: Record) =>
@@ -46,3 +51,24 @@ describe('eventAccessibilityLabel', () => {
.toMatch(/^\(No title\), Monday, Nov(ember)? 2, 2026, 9:00 AM – 9:15 AM, Cancelled$/);
});
});
+
+describe('header and chip buttons', () => {
+ it('names the month button by the month it shows, not "Click to change month"', () => {
+ expect(monthButtonAccessibilityLabel('October 2026', t)).toBe('October 2026, change month');
+ });
+
+ it('names the cross on a participant chip by the person it removes', () => {
+ expect(participantRemoveAccessibilityLabel({ name: 'Ana Lima', email: 'ana@example.com' }, t)).toBe('Remove Ana Lima');
+ expect(participantRemoveAccessibilityLabel({ name: '', email: 'ana@example.com' }, t)).toBe('Remove ana@example.com');
+ });
+
+ it('is what the calendar header and the participant chips use', async () => {
+ const fs = await import('node:fs');
+ const path = await import('node:path');
+ const screen = fs.readFileSync(path.resolve(__dirname, '../../screens/CalendarScreen.tsx'), 'utf8');
+ const chips = fs.readFileSync(path.resolve(__dirname, '../../components/calendar/ParticipantInput.tsx'), 'utf8');
+ expect(screen).toMatch(/accessibilityLabel=\{monthButtonAccessibilityLabel\(/);
+ expect(screen).not.toMatch(/mini_calendar_change/);
+ expect(chips).toMatch(/accessibilityLabel=\{participantRemoveAccessibilityLabel\(a, t\)\}/);
+ });
+});
diff --git a/src/lib/calendar-a11y.ts b/src/lib/calendar-a11y.ts
index 0a55b64a..98cb478f 100644
--- a/src/lib/calendar-a11y.ts
+++ b/src/lib/calendar-a11y.ts
@@ -11,6 +11,20 @@ type Translate = (key: string, fallback?: string, params?: Record