fix: improve keyboard navigation and screen-reader labels (#1445)

This commit is contained in:
Björn F.
2026-04-21 22:21:23 +02:00
committed by GitHub
parent 605c8b2ba4
commit a9fdab10f1
7 changed files with 55 additions and 5 deletions

View File

@@ -17,7 +17,7 @@
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger
<DropdownMenu.Trigger aria-label={m.my_account()}
><Avatar.Root class="size-9">
<Avatar.Image src={cachedProfilePicture.getUrl($userStore!.id)} />
</Avatar.Root></DropdownMenu.Trigger

View File

@@ -77,7 +77,11 @@
const delayUpdateLink = () => `${layout().total * ROW_STAGGER}ms`;
</script>
<nav class="text-muted-foreground grid gap-2 text-sm">
<nav
class="text-muted-foreground grid gap-2 text-sm"
aria-label={m.settings()}
data-sveltekit-keepfocus
>
{#each items as item, i}
{#if item.children?.length}
{@const id = groupId(item, i)}

View File

@@ -223,7 +223,16 @@
{/if}
{#each visibleColumns as column}
<Table.Head class={cn(column.sortable && 'p-0')}>
<Table.Head
class={cn(column.sortable && 'p-0')}
aria-sort={column.sortable
? requestOptions.sort?.column === column.column
? requestOptions.sort?.direction === 'asc'
? 'ascending'
: 'descending'
: 'none'
: undefined}
>
{#if column.sortable}
<Button
variant="ghost"

View File

@@ -13,6 +13,7 @@
<th
bind:this={ref}
data-slot="table-head"
scope="col"
class={cn(
'text-foreground h-12 px-4 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
className

View File

@@ -68,7 +68,14 @@
<p class="text-muted-foreground mt-2">{m.enter_the_code_you_received_to_sign_in()}</p>
{/if}
<form onsubmit={preventDefault(authenticate)} class="w-full max-w-[450px]">
<Input id="Code" class="mt-7" placeholder={m.code()} bind:value={code} type="text" />
<Input
id="Code"
class="mt-7"
placeholder={m.code()}
aria-label={m.code()}
bind:value={code}
type="text"
/>
<div class="mt-8 flex justify-between gap-2">
<Button variant="secondary" class="flex-1" href={backHref}>{m.go_back()}</Button>
<Button class="flex-1" type="submit" {isLoading}>{m.submit()}</Button>

View File

@@ -63,7 +63,14 @@
<p class="text-muted-foreground mt-2" in:fade>
{m.enter_your_email_address_to_receive_an_email_with_a_login_code()}
</p>
<Input id="Email" class="mt-7" placeholder={m.your_email()} bind:value={email} type="email" />
<Input
id="Email"
class="mt-7"
placeholder={m.your_email()}
aria-label={m.email()}
bind:value={email}
type="email"
/>
<div class="mt-8 flex justify-between gap-2">
<Button variant="secondary" class="flex-1" href={'/login/alternative' + page.url.search}
>{m.go_back()}</Button

View File

@@ -0,0 +1,22 @@
import test, { expect } from '@playwright/test';
import { cleanupBackend } from '../utils/cleanup.util';
test.beforeEach(async () => await cleanupBackend());
test('settings sidebar has an accessible name', async ({ page }) => {
await page.goto('/settings/account');
const nav = page.getByRole('navigation', { name: 'Settings' });
await expect(nav).toBeVisible();
});
test('keyboard focus stays on sidebar link after navigating', async ({ page }) => {
await page.goto('/settings/account');
const auditLog = page.getByRole('link', { name: 'Audit Log' });
await auditLog.focus();
await page.keyboard.press('Enter');
await page.waitForURL('**/settings/audit-log');
await expect(auditLog).toBeFocused();
});