perf(a11y): make menu traversable only when it is open (#1491)

Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
pull/1740/head
Urata Daiki 2 years ago committed by GitHub
parent 7a737845e5
commit 257f9e68e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -22,6 +22,7 @@ watch(() => route.path, closeSidebar)
useCloseSidebarOnEscape(isSidebarOpen, closeSidebar)
provide('close-sidebar', closeSidebar)
provide('is-sidebar-open', isSidebarOpen)
const { frontmatter } = useData()
</script>

@ -1,11 +1,12 @@
<script lang="ts" setup>
import type { DefaultTheme } from 'vitepress/theme'
import { computed, inject } from 'vue'
import { Ref, computed, inject, ref, watchEffect } from 'vue'
import { useData } from 'vitepress'
import { useSidebar } from '../composables/sidebar.js'
import { isActive } from '../support/utils.js'
import VPLink from './VPLink.vue'
withDefaults(
const props = withDefaults(
defineProps<{ item: DefaultTheme.SidebarItem; depth?: number }>(),
{ depth: 1 }
)
@ -14,16 +15,32 @@ const { page, frontmatter } = useData()
const maxDepth = computed<number>(
() => frontmatter.value.sidebarDepth || Infinity
)
const active = computed(() =>
isActive(page.value.relativePath, props.item.link)
)
const { isSidebarEnabled } = useSidebar()
const closeSideBar = inject('close-sidebar') as () => void
const isSidebarOpen = inject('is-sidebar-open') as Ref<boolean>
const link = ref<InstanceType<typeof VPLink> | null>(null)
watchEffect(() => {
if (isSidebarOpen.value && active.value) {
link.value?.$el?.focus()
}
})
</script>
<template>
<VPLink
class="link"
:class="{ active: isActive(page.relativePath, item.link) }"
:class="{ active }"
:style="{ paddingLeft: 16 * (depth - 1) + 'px' }"
:href="item.link"
:tabindex="isSidebarEnabled || isSidebarOpen ? 0 : -1"
@click="closeSideBar"
ref="link"
>
<span v-html="item.text" class="link-text" :class="{ light: depth > 1 }"></span>
</VPLink>

@ -1,10 +1,12 @@
import { computed, onMounted, onUnmounted, Ref, ref, watchEffect } from 'vue'
import { useData, useRoute } from 'vitepress'
import { useMediaQuery } from '@vueuse/core'
import { getSidebar } from '../support/sidebar.js'
export function useSidebar() {
const route = useRoute()
const { theme, frontmatter } = useData()
const is960 = useMediaQuery('(min-width: 960px)')
const isOpen = ref(false)
@ -28,6 +30,8 @@ export function useSidebar() {
)
})
const isSidebarEnabled = computed(() => hasSidebar.value && is960.value)
function open() {
isOpen.value = true
}
@ -45,6 +49,7 @@ export function useSidebar() {
sidebar,
hasSidebar,
hasAside,
isSidebarEnabled,
open,
close,
toggle

Loading…
Cancel
Save