test: lock semantic and no-script portfolio behavior

This commit is contained in:
2026-09-02 03:12:12 +03:00
parent 3638a0beef
commit 091ff70deb
8 changed files with 811 additions and 2 deletions

View File

@@ -10,7 +10,7 @@ defineProps<{
<template>
<section :id="id" class="portfolio-section" :aria-labelledby="`${id}-heading`" :data-section-index="index">
<p class="route-label">{{ String(index).padStart(2, '0') }} / {{ eyebrow }}</p>
<h2 :id="`${id}-heading`">{{ heading }}</h2>
<h2 :id="`${id}-heading`" tabindex="-1">{{ heading }}</h2>
<slot />
</section>
</template>

View File

@@ -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<HTMLElement>(
':scope > h2[tabindex="-1"]',
);
if (heading === undefined || heading === null) return;
requestAnimationFrame(() => heading.focus({ preventScroll: true }));
};
</script>
<template>
<nav class="site-navigation" aria-label="Portfolio sections">
<ul>
<li v-for="item in items" :key="item.id">
<a :href="`#${item.id}`">{{ item.label }}</a>
<a :href="`#${item.id}`" @click="focusActivatedSection">{{ item.label }}</a>
</li>
</ul>
</nav>