From bf93640af82793885ace2a12b3224de9d2cbaae4 Mon Sep 17 00:00:00 2001 From: Cyril Date: Mon, 16 Mar 2026 13:30:59 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BF=EF=B8=8F(frontend)=20skip=20link=20as?= =?UTF-8?q?=20anchor=20instead=20of=20button?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace button with anchor link --- CHANGELOG.md | 2 +- .../e2e/__tests__/app-impress/header.spec.ts | 16 ++++---- .../impress/src/components/SkipToContent.tsx | 41 +++---------------- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 280f0fcd..7c20d1a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to - 💫(frontend) fix the help button to the bottom in tree #2073 - ♿️(frontend) improve version history list accessibility #2033 - ♿️(frontend) fix more options menu feedback for screen readers #2071 +- ♿(frontend) focus skip link on headings and skip grid dropzone #1983 ## [v4.8.2] - 2026-03-19 @@ -68,7 +69,6 @@ and this project adheres to - ⬆️(frontend) upgrade Next.js to v16 #1980 - ♿️(frontend) fix aria-label and landmark on document banner state #1986 - 🌐(i18n) add "new window" translation key for waffle aria-label #1984 -- ♿(frontend) focus skip link on headings and skip grid dropzone #1983 ### Fixed diff --git a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts index 1eb78ea2..237a437d 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts @@ -196,18 +196,18 @@ test.describe('Header: Skip to Content', () => { }) => { await page.goto('/'); - // Wait for skip button to be mounted (client-side only component) - const skipButton = page.getByRole('button', { name: 'Go to content' }); - await skipButton.waitFor({ state: 'attached' }); + // Wait for skip link to be mounted (client-side only component) + const skipLink = page.getByRole('link', { name: 'Go to content' }); + await skipLink.waitFor({ state: 'attached' }); - // First TAB shows the skip button + // First TAB shows the skip link await page.keyboard.press('Tab'); - // The skip button should be visible and focused - await expect(skipButton).toBeFocused(); - await expect(skipButton).toBeVisible(); + // The skip link should be visible and focused + await expect(skipLink).toBeFocused(); + await expect(skipLink).toBeVisible(); // Clicking moves focus to the page heading - await skipButton.click(); + await skipLink.click(); const pageHeading = page.getByRole('heading', { name: 'All docs', level: 2, diff --git a/src/frontend/apps/impress/src/components/SkipToContent.tsx b/src/frontend/apps/impress/src/components/SkipToContent.tsx index a169467a..1ba63c9f 100644 --- a/src/frontend/apps/impress/src/components/SkipToContent.tsx +++ b/src/frontend/apps/impress/src/components/SkipToContent.tsx @@ -1,38 +1,17 @@ import { Button } from '@gouvfr-lasuite/cunningham-react'; -import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { css } from 'styled-components'; import { Box } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; +import { MAIN_LAYOUT_ID } from '@/layouts/conf'; import { focusMainContentStart } from '@/layouts/utils'; export const SkipToContent = () => { const { t } = useTranslation(); - const router = useRouter(); const { spacingsTokens } = useCunninghamTheme(); const [isVisible, setIsVisible] = useState(false); - // Reset focus after route change so first TAB goes to skip link - useEffect(() => { - const handleRouteChange = () => { - (document.activeElement as HTMLElement)?.blur(); - - document.body.setAttribute('tabindex', '-1'); - document.body.focus({ preventScroll: true }); - - setTimeout(() => { - document.body.removeAttribute('tabindex'); - }, 100); - }; - - router.events.on('routeChangeComplete', handleRouteChange); - return () => { - router.events.off('routeChangeComplete', handleRouteChange); - }; - }, [router.events]); - const handleClick = (e: React.MouseEvent) => { e.preventDefault(); const focusTarget = focusMainContentStart(); @@ -43,21 +22,12 @@ export const SkipToContent = () => { }; return ( - +