diff --git a/apps/web/e2e/content.spec.ts b/apps/web/e2e/content.spec.ts index 993712f..2c59712 100644 --- a/apps/web/e2e/content.spec.ts +++ b/apps/web/e2e/content.spec.ts @@ -62,7 +62,7 @@ test('page lifecycle: create via the sidebar, rename, appears in the sidebar', a const page = await context.newPage(); await page.goto(`/p/${pond.slug}`); await page.getByRole('button', { name: /new page|neue seite/i }).click(); - await page.getByLabel(/title|titel/i).fill(title); + await page.locator('.sidebar').getByLabel(/title|titel/i).fill(title); await page.getByRole('button', { name: /create|erstellen/i }).click(); await expect(page.locator('.sidebar__page--active')).toHaveText(title); diff --git a/apps/web/e2e/sidebar.spec.ts b/apps/web/e2e/sidebar.spec.ts index f101a5e..2d4a571 100644 --- a/apps/web/e2e/sidebar.spec.ts +++ b/apps/web/e2e/sidebar.spec.ts @@ -110,7 +110,7 @@ test('new-page flow: button opens a title prompt and the editor opens on create' await page.goto(`/p/${pond.slug}`); await page.getByRole('button', { name: /new page|neue seite/i }).click(); - await page.getByLabel(/title|titel/i).fill(title); + await page.locator('.sidebar').getByLabel(/title|titel/i).fill(title); await page.getByRole('button', { name: /create|erstellen/i }).click(); await expect(page).toHaveURL(new RegExp(`/p/${pond.slug}/.+`)); diff --git a/apps/web/src/layout/AppLayout.tsx b/apps/web/src/layout/AppLayout.tsx index afae63a..5d8ce8e 100644 --- a/apps/web/src/layout/AppLayout.tsx +++ b/apps/web/src/layout/AppLayout.tsx @@ -1,4 +1,5 @@ import { useEffect, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { Outlet } from 'react-router-dom'; import { usePersistentState } from '../lib/use-persistent-state'; @@ -10,6 +11,7 @@ import { clampSidebarWidth, SIDEBAR_DEFAULT_WIDTH_REM, SidebarResizer } from './ import { TopBar } from './TopBar'; export function AppLayout(): React.JSX.Element { + const { t } = useTranslation(); const [sidebarCollapsed, setSidebarCollapsed] = usePersistentState('ui.sidebar.collapsed', false); const [sidebarWidth, setSidebarWidth] = usePersistentState( 'ui.sidebar.width', @@ -53,6 +55,10 @@ export function AppLayout(): React.JSX.Element {
+ {/* First tab stop: jump over topbar + sidebar (#166, WCAG 2.4.1). */} + + {t('layout.skipToContent')} + setSidebarCollapsed(!sidebarCollapsed)} @@ -61,13 +67,20 @@ export function AppLayout(): React.JSX.Element { className="app-body" style={{ '--sidebar-width': `${widthRem}rem` } as React.CSSProperties} > - - {!collapsed && } +