diff --git a/playwright.config.ts b/playwright.config.ts index 371154a..ff133fc 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -2,6 +2,10 @@ import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests/browser', + workers: 4, + use: { + serviceWorkers: 'block', + }, projects: [ { name: 'desktop-chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'mobile-chromium', use: { ...devices['Pixel 5'] } }, diff --git a/src/components/PortfolioSection.vue b/src/components/PortfolioSection.vue index 8ac7d5f..166cd2e 100644 --- a/src/components/PortfolioSection.vue +++ b/src/components/PortfolioSection.vue @@ -10,7 +10,7 @@ defineProps<{ diff --git a/src/components/SiteNavigation.vue b/src/components/SiteNavigation.vue index dbeb8fe..981d1a0 100644 --- a/src/components/SiteNavigation.vue +++ b/src/components/SiteNavigation.vue @@ -2,13 +2,42 @@ import type { SectionId } from '@/content/types'; defineProps<{ items: ReadonlyArray<{ id: SectionId; label: string }> }>(); + +const focusActivatedSection = (event: MouseEvent): void => { + if ( + event.defaultPrevented || + event.button !== 0 || + event.altKey || + event.ctrlKey || + event.metaKey || + event.shiftKey || + !(event.currentTarget instanceof HTMLAnchorElement) + ) { + return; + } + + let sectionId: string; + try { + sectionId = decodeURIComponent(event.currentTarget.hash.slice(1)); + } catch { + return; + } + + const section = document.getElementById(sectionId); + const heading = section?.querySelector( + ':scope > h2[tabindex="-1"]', + ); + if (heading === undefined || heading === null) return; + + requestAnimationFrame(() => heading.focus({ preventScroll: true })); +};