fix(invites): i18n legend + touch target in UserGroupsSection

- legend uses m.admin_new_invite_groups() instead of hardcoded "Gruppen"
  so screen readers announce the correct string in en/es locales
- label gets min-h-[44px] for WCAG 2.2 touch target compliance
- add test asserting fieldset accessible name comes from i18n key
- add test documenting empty-groups-no-error renders no checkboxes/banner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-14 16:43:53 +02:00
parent 558b3ebe07
commit 9230e4a531
2 changed files with 39 additions and 2 deletions

View File

@@ -1,4 +1,6 @@
<script lang="ts">
import { m } from '$lib/paraglide/messages.js';
let {
groups,
selectedGroupIds = []
@@ -11,9 +13,9 @@ let selected = $state<string[]>([...selectedGroupIds]);
</script>
<fieldset class="flex flex-wrap gap-3 border-none p-0">
<legend class="sr-only">Gruppen</legend>
<legend class="sr-only">{m.admin_new_invite_groups()}</legend>
{#each groups as group (group.id)}
<label class="inline-flex items-center gap-2 text-sm text-ink-2">
<label class="inline-flex min-h-[44px] items-center gap-2 text-sm text-ink-2">
<input
type="checkbox"
name="groupIds"

View File

@@ -334,4 +334,39 @@ describe('admin/invites page', () => {
const alert = document.querySelector('[role="alert"]');
expect(alert).not.toBeNull();
});
it('checkbox group fieldset has accessible name from i18n key (not hardcoded German)', async () => {
render(AdminInvitesPage, {
props: {
data: {
...baseData(),
groups: [{ id: 'g-1', name: 'Familie', permissions: ['READ_ALL'] }],
groupsLoadError: null
}
}
});
await page
.getByRole('button', { name: /neue einladung/i })
.first()
.click();
// m.admin_new_invite_groups() returns "Gruppen (optional)" in de locale
// The hardcoded legend "Gruppen" would not match this accessible name
await expect.element(page.getByRole('group', { name: 'Gruppen (optional)' })).toBeVisible();
});
it('shows no checkboxes and no warning when groups list is empty and no error', async () => {
render(AdminInvitesPage, {
props: { data: { ...baseData(), groups: [], groupsLoadError: null } }
});
await page
.getByRole('button', { name: /neue einladung/i })
.first()
.click();
expect(document.querySelectorAll('input[name="groupIds"]')).toHaveLength(0);
expect(document.querySelector('.bg-amber-50')).toBeNull();
});
});